/**
 * todo
 * @pluve/fetch 支持传入自定义参数后，底层请求库切换至 @pluve/fetch
 */
import request from 'umi-request';
import { CANCEL_HTTP_STATUS } from '@/constants';
import { setRequestTask, removeRequestTask, getOpenxHead } from './request-tasks';
/**
 * request
 * @params options
 * @params options.url 请求url
 * @params options.method 请求方法
 * @params options.data
 * @params options.isOpenXHeader 是否自动携带openXHeader
 * @params options.requestTaskName 请求任务名
 */
export default async options => {
  const userInfo = getOpenxHead();

  const { url, data = {}, isOpenXHeader = true, requestTaskName, ...restOptions } = options;

  const controller = new AbortController();
  const { signal } = controller;

  // 任务加入队列
  setRequestTask(requestTaskName, controller);

  const newOptions = {
    skipErrorHandler: true,
    signal,
    data: {
      ...(isOpenXHeader
        ? {
            _openx_head: {
              REQUEST_FROM_H5: true,
              ...userInfo,
            },
          }
        : {}),
      ...data,
    },
    timeout: 1000 * 60, // 默认超时60秒
    ...restOptions,
  };

  try {
    const result = await request(url, newOptions);
    // 任务从队列移除
    removeRequestTask(requestTaskName);
    return result;
  } catch (initError) {
    const err = initError;
    // 判断是否为取消请求
    const isCancelError = err.name === 'AbortError';
    // 避免err.response为null（如 err.name 为 'AbortError' 时）等情形
    if (!err.response) {
      err.response = {};
    }
    const { response: { status = isCancelError ? CANCEL_HTTP_STATUS : '', statusText = '' } = {}, message = '' } = err;
    let errorText = message || statusText;
    try {
      const errorJSON = await err.response.json();
      if (errorJSON?.message) {
        errorText = errorJSON.message;
      }
    } catch (error) {
      // do nothing
    }
    const error = new Error(errorText);
    error.status = status;
    error.url = url;
    if (!isCancelError) {
      // 任务从队列移除
      removeRequestTask(requestTaskName);
    }
    throw error;
  }
};
